热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

也就是|雪球_详解主成分分析PCA与奇异值分解SVD降维后的矩阵components_&inverse_transform菜菜的sklearn课堂笔记

篇首语:本文由编程笔记#小编为大家整理,主要介绍了详解主成分分析PCA与奇异值分解SVD-降维后的矩阵components_&inverse_transform菜菜的sklearn课堂笔记相

篇首语:本文由编程笔记#小编为大家整理,主要介绍了详解主成分分析PCA与奇异值分解SVD-降维后的矩阵components_ & inverse_transform菜菜的sklearn课堂笔记相关的知识,希望对你有一定的参考价值。



V(k,n)这个矩阵保存在.components_这个属性当中
我们之前谈到过PCA与特征选择的区别,即特征选择后的特征矩阵是可解读的,而PCA降维后的特征矩阵式不可解读的:PCA是将已存在的特征进行压缩,降维完毕后的特征不是原本的特征矩阵中的任何一个特征,而是通过某些方式组合起来的新特征。通常来说,在新的特征矩阵生成之前,我们无法知晓PCA都建立了怎样的新特征向量,新特征矩阵生成之后也不具有可读性,我们无法判断新特征矩阵的特征是从原数据中的什么特征组合而来,新特征虽然带有原始数据的信息,却已经不是原数据上代表着的含义了。
但是其实,在矩阵分解时,PCA是有目标的:在原有特征的基础上,找出能够让信息尽量聚集的新特征向量。在sklearn使用的PCA和SVD联合的降维方法中,这些新特征向量组成的新特征空间其实就是V(k,n)。当V(k,n)是数字时,我们无法判断V(k,n)和原有的特征究竟有着怎样千丝万缕的数学联系。但是,如果原特征矩阵是图像,V(k,n)这个空间矩阵也可以被可视化的话,我们就可以通过两张图来比较,就可以看出新特征空间究竟从原始数据里提取了什么重要的信息

我们以人脸识别中属性components_为例

from sklearn.datasets import fetch_lfw_people
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np
faces = fetch_lfw_people(min_faces_per_person=60) # 实例化
# min_faces_per_person:在数据集中每个人取出n张脸图
print(faces.DESCR) # 需要的话自己看吧
faces.data.shape
# 每一行是样本,即1348个样本
# 列式样本相关的所有特征,即2914个特征
# 因此,可视化这一部分没有意义
---
(1348, 2914)
faces.images.shape # 注意是三维的
# 严格来说,这个才是图像的特征矩阵
# 1348是矩阵中图像的个数
# 62是每个图像的特征矩阵的行,行上有62个像素
# 42是每个图像的特征矩阵的列,列上有47个像素
# 之前的2914=62*47,一张图就要有一行一列,可以看做一个表
# 因此我们可以对62*47这一部分进行可视化
---
(1348, 62, 47)
X = faces.data
# 之前的plt.figure是无法画多个图的
fig, axes = plt.subplots(4,5 # 子图4行5列。现在直接执行会给4*5=20个框,其他什么也没有
# 4,5表示要画20个图,在这里也就是20张脸,可以写其他数
,figsize=(8,4) # 画布的尺寸和比例和大小,8代表行,4代表列
# figsize的对象是figure不是某一个subplot
,subplot_kw="xticks":[],"yticks":[] # 不显示坐标轴
)

fig # 生成的一张纸

axes # 4行5列,matplotlib的对象
# axes中的一个对象对应fig中的一个空格
---
array([[,
,
,……
# 4*5的array,里面都是matplotlib对象
axes.shape
---
(4, 5)
axes[0,0] # 指定那个对象和一般的矩阵一样
axes[0,0].imshow(faces.images[0,:,:])
# 生成一个更新过的matplotlib对象
# 我们只是改变了axes对象,在这里执行完这个cell显示图像
# 只有再次看fig画布才看看到效果
# imshow要求的数据格式必须是一个(m,n)格式的矩阵,即每个数据都是一张单独的图,我们需要遍历的是faces.images,其结构是(1277, 62, 47)
fig

我们要花$4\\times 5=20$个图,二维结构,可以有两种循环方式,一种是使用索引,循环一次同时生成一列上的三个图;另一种是把数据拉成一维,循环一次只生成一个图。这里我们选择后者

[*enumerate(axes.flat)]
---
[(0, ),
(1, ),
(2, ),
(3, ),
# flat降维成一维
# enumerate每个对象带序号构成一个元组,因为是惰性对象,所以在列表中可以用*打开

填充所有子图

for i, ax in enumerate(axes.flat):
ax.imshow(faces.images[i,:,:],cmap=gray) # 选择色彩的模式,原本显示绿色,设置显示黑白
fig

降维,并获取components_

pca = PCA(150).fit(X) # X = faces.data,注意faces.data.shape为(1348, 2914)
V = pca.components_ # 是V^T而不是V
V.shape
---
(150, 2914)
V[0].shape # 这一行的shape,意义不大
---
(2914,)
V[0].reshape(62,47).shape # 这里实际上是被选中的降维所用的特征向量进行reshape
---
(62, 47)
fig, axes = plt.subplots(5,10,figsize=(8,4),subplot_kw = "xticks":[],"yticks":[])
for i,ax in enumerate(axes.flat):
ax.imshow(V[i,:].reshape(62,47),cmap=gray)
# 这里对V进行可视化,显然画的不是图片,而是特征向量
# 个人理解,这里的V是150*2914,150个特征向量也就是150个最重要的点
# X*V,也就是通过X对V这150个特征组成的图像进行加权得到降维后的图像
# 越靠前的V越重要,越靠后的区分度越小
# 前几个特征也就是这个前几个图像主要关注了五官的位置,光照等

可以看出,比起降维前的数据,新特征空间可视化后的人脸非常模糊,这是因为原始数据还没有被映射到特征空间中。但是可以看出,整体比较亮的图片,获取的信息较多,整体比较暗的图片,却只能看见黑漆漆的一块。在比较亮的图片中,眼睛,鼻子,嘴巴,都相对清晰,脸的轮廓,头发之类的比较模糊。
这说明,新特征空间里的特征向量们,大部分是"五官"和"亮度"相关的向量,所以新特征向量上的信息肯定大部分是由原数据中和"五官"和"亮度"相关的特征中提取出来的。到这里,我们通过可视化新特征空间V,解释了一部分降维后的特征:虽然显示出来的数字看着不知所云,但画出来的图表示,这些特征是和”五官“以及”亮度“有关的。这也再次证明了,PCA能够将原始数据集中重要的数据进行聚集。

这里关于白化其实在sklearn里就是一个参数

PCA(
[n_compOnents=None, copy=True, whiten=False, "svd_solver=auto", tol=0.0, "iterated_power=auto", random_state=None],
)
# whiten:是否PCA后进行白化

个人理解,我们PCA是求的$X_dr=X \\cdot V$,其中$V$是特征向量组成的矩阵,白化PCA就是$X_w= X \\cdot V \\cdot \\Lambda^- \\frac12$,这里$\\Lambda$就是协方差矩阵$S$的特征值
$$
\\beginaligned
\\Sigma_w&=\\frac1mX_w^TX_w\\
&=\\frac1m\\Lambda^- \\frac12V^TX^T \\cdot XV\\Lambda^- \\frac12\\
&=\\Lambda^- \\frac12V^T\\cdot \\frac1mX^TX \\cdot V \\Lambda^- \\frac12\\
&=\\Lambda^- \\frac12 V^TS V \\Lambda^- \\frac12\\
&=\\Lambda^- \\frac12V^T\\cdot V \\Lambda V^T\\cdot V\\Lambda^- \\frac12\\
&=\\textI
\\endaligned
$$
因此我们说数据在经过PCA白化以后,其协方差矩阵是一个单位矩阵,各维度不线性相关,且每个维度方差都是1


inverse_transform

在特征工程课中,我们学到了接口inverse_transform,可以将我们归一化,标准化,甚至做过哑变量的特征矩阵还原回原始数据中的特征矩阵,这几乎在向我们暗示,任何有inverse_transform这个接口的过程都是可逆的。PCA应该也是如此。在sklearn中,我们通过让原特征矩阵X右乘新特征空间矩阵$V_((k,n))$来生成新特征矩阵$X_dr$,那理论上来说,让新特征矩阵$X_dr$右乘V(k,n)的逆矩阵$V^-1((k,n))$,就可以将新特征矩阵$Xdr$还原为X。

用上面人脸识别看PCA降维后的信息保存量

from sklearn.datasets import fetch_lfw_people
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np
faces = fetch_lfw_people(min_faces_per_person=60)
X = faces.data
X.shape
---
(1348, 2914)
pca = PCA(150)
X_dr = pca.fit_transform(X)
X_dr.shape
---
(1348, 150)
X_inverse = pca.inverse_transform(X_dr)
X_inverse.shape
# 期待X_inverse和原数据有相同的结构,如果相同,我们就说inverse_transform实现了降维过程的逆转
# 维度相同,即使inverse_transform将降维后的数据映射回原数据所在的维度空间中,但信息已经损失了
---
(1348, 2914)
fig, ax = plt.subplots(2,10,figsize=(10,2.5)
,subplot_kw=xticks:[],yticks:[]
)
for i in range(10):
ax[0,i].imshow(faces.images[i,:,:],cmap=binary_r)
ax[1,i].imshow(X_inverse[i].reshape(62,47),cmap=binary_r)
fig
# 第一行是原数据,第二行是inverse_transform后返回的数据
---

可以明显看出,这两组数据可视化后,由降维后再通过inverse_transform转换回原维度的数据画出的图像和原数据画的图像大致相似,但原数据的图像明显更加清晰。这说明,inverse_transform并没有实现数据的完全逆转。这是因为,在降维的时候,部分信息已经被舍弃了,$X_dr$中往往不会包含原数据100%的信息,所以在逆转的时候,即便维度升高,原数据中已经被舍弃的信息也不可能再回来了。所以,降维不是完全可逆的。
inverse_transform的功能,是基于$X_dr$中的数据进行升维,将数据重新映射到原数据所在的特征空间中,而并非恢复所有原有的数据。但同时,我们也可以看出,降维到300以后的数据,的确保留了原数据的大部分信息,所以图像看起来,才会和原数据高度相似,只是稍稍模糊罢了。


推荐阅读
  • Python使用Pillow包生成验证码图片的方法
    本文介绍了使用Python中的Pillow包生成验证码图片的方法。通过随机生成数字和符号,并添加干扰象素,生成一幅验证码图片。需要配置好Python环境,并安装Pillow库。代码实现包括导入Pillow包和随机模块,定义随机生成字母、数字和字体颜色的函数。 ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • EzPP 0.2发布,新增YAML布局渲染功能
    EzPP发布了0.2.1版本,新增了YAML布局渲染功能,可以将YAML文件渲染为图片,并且可以复用YAML作为模版,通过传递不同参数生成不同的图片。这个功能可以用于绘制Logo、封面或其他图片,让用户不需要安装或卸载Photoshop。文章还提供了一个入门例子,介绍了使用ezpp的基本渲染方法,以及如何使用canvas、text类元素、自定义字体等。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了在Python中使用zlib模块进行字符串的压缩与解压缩的方法,并探讨了其在内存优化方面的应用。通过压缩存储URL等长字符串,可以大大降低内存消耗,虽然处理时间会增加,但是整体效果显著。同时,给出了参考链接,供进一步学习和应用。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • 开源Keras Faster RCNN模型介绍及代码结构解析
    本文介绍了开源Keras Faster RCNN模型的环境需求和代码结构,包括FasterRCNN源码解析、RPN与classifier定义、data_generators.py文件的功能以及损失计算。同时提供了该模型的开源地址和安装所需的库。 ... [详细]
author-avatar
mobiledu2502862267
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有